package com.bestcem.xm.survey.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bestcem.xm.component.mybatis.service.impl.XmServiceImpl;
import com.bestcem.xm.componet.redis.service.RedisService;
import com.bestcem.xm.survey.entity.SurveyRespondentPropData;
import com.bestcem.xm.survey.mapper.SurveyRespondentPropDataMapper;
import com.bestcem.xm.survey.service.SurveyRespondentPropDataService;
import com.bestcem.xm.survey.util.SurveyConstant;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.bestcem.xm.survey.enums.RespondentStatusEnum.RESPONDENT_STATUS_FINISH;

/**
 * @author guita
 * @description 针对表【ds_survey_respondentpropdata】的数据库操作Service实现
 * @createDate 2023-01-09 15:15:38
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SurveyRespondentPropDataServiceImpl extends XmServiceImpl<SurveyRespondentPropDataMapper, SurveyRespondentPropData>
        implements SurveyRespondentPropDataService {

    private @NonNull RedisService redisService;

    @Override
    public Map<String, Object> getSubmitedCount(String pid, Integer qid, List<Integer> seq_list, Boolean cached) {
        //key = f'__submited_count_{pid}_{qid}'
        String key = String.format(SurveyConstant.SURVEY_SUBMITED_COUNT_FORMAT, pid, qid);
        if (cached) {
            Map<Object, Object> map = redisService.hashGetAll(key);
            Map<String, Object> ret;
            if (!ObjectUtils.isEmpty(map)) {
                ret = map.keySet().stream().collect(Collectors.toMap(Object::toString, map::get));
                Set<String> exp_set = seq_list.stream().map(String::valueOf).collect(Collectors.toSet());
                exp_set.add("total_count");
                if (CollUtil.containsAll(ret.keySet(), exp_set)) {
                    return ret;
                }
            }

            ret = getSubmitedCount(pid, qid, seq_list, Boolean.FALSE);
            if (!ObjectUtils.isEmpty(ret)) {
                redisService.hashSetAll(key, ret, 60, TimeUnit.SECONDS);
            }
            return ret;
        }

        //查表
        //python 写的和弱智一样
        //一条sql就能解决
        /*SELECT value,count(value) as count from ds_survey_respondentpropdata
                WHERE
        project_id='64faf93dcff78909563cdda9'
        AND
                status=1 and qgid=135 and value in (7,10)
        GROUP BY value;*/
        QueryWrapper<SurveyRespondentPropData> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("value,count(value) as count");
        queryWrapper.eq("project_id", pid);
        queryWrapper.eq("status", RESPONDENT_STATUS_FINISH.getValue());
        queryWrapper.eq("qgid", qid);
        queryWrapper.in("value", seq_list);
        queryWrapper.groupBy("value");
        List<Map<String, Object>> result = baseMapper.selectMaps(queryWrapper);
        Map<String, Object> ret = new HashMap<>();
        AtomicInteger total_count = new AtomicInteger();
        result.forEach(it -> {
            ret.put(it.get("value").toString(), it.get("count"));
            total_count.addAndGet(Integer.parseInt(it.get("count").toString()));
        });

        /*if (!ObjectUtils.isEmpty(ret)) {
            Set<String> keySet = ret.keySet();
            //补上未答选项
            seq_list.forEach(seq -> {
                if (!keySet.contains(seq.toString())) {
                    ret.put(seq.toString(), 0);
                }
            });
        } else {
            seq_list.forEach(seq -> {
                ret.put(seq.toString(), 0);
            });
        }*/
        seq_list.forEach(seq -> {
            ret.putIfAbsent(seq.toString(), 0);
        });
        ret.put("total_count", total_count.get());
        return ret;
    }
}




